package cn.hist.hfp.util;

import cn.hist.hfp.RoleType;
import cn.hist.hfp.entity.ManagerValidation;
import cn.hist.hfp.entity.UserValidation;
import cn.hist.hfp.exception.BusinessException;
import cn.hist.hfp.exception.ErrorCode;
import cn.hist.hfp.service.ManagerValidationService;
import cn.hist.hfp.service.UserValidationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Authentication {

    private final
    TokenUtil tokenUtil;

    private final
    UserValidationService userValidationService;

    private final
    ManagerValidationService managerValidationService;

    @Autowired
    public Authentication(TokenUtil tokenUtil, UserValidationService userValidationService, ManagerValidationService managerValidationService) {
        this.tokenUtil = tokenUtil;
        this.userValidationService = userValidationService;
        this.managerValidationService = managerValidationService;
    }

    public void permissionCheck(String token, RoleType... permittedRoles) {
        if (permittedRoles == null || permittedRoles.length == 0)
            return;

        if (tokenUtil.isTokenExpired(token))
            throw new BusinessException(ErrorCode.INFO_EXPIRED);

        if (!getStoredToken(token).equals(token))
            throw new BusinessException(ErrorCode.INFO_EXPIRED);

        for (RoleType roleType: permittedRoles) {
            String roleName = roleType.getName();
            if (tokenUtil.getIdentityInfo(token).startsWith(roleName))
                return;
        }

        throw new BusinessException(ErrorCode.PERMISSION_DENIED);
    }

    public String refreshToken(String oldToken) {
        String newToken =  tokenUtil.refreshToken(oldToken);

        String identity = tokenUtil.getIdentityInfo(newToken);
        String roleName = identity.split(" ")[0];
        int id = Integer.parseInt(identity.split(" ")[1]);

        if (roleName.equals(RoleType.USER.getName())) {
            UserValidation userValidation = userValidationService.findByUserId(id);
            userValidation.setToken(newToken);
            userValidationService.update(userValidation);
        } else {
            ManagerValidation managerValidation = managerValidationService.findByManagerId(id);
            managerValidation.setToken(newToken);
            managerValidationService.update(managerValidation);
        }
        return newToken;
    }

    private String getStoredToken(String token) {
       String identity = tokenUtil.getIdentityInfo(token);
       String roleName = identity.split(" ")[0];
       int id = Integer.parseInt(identity.split(" ")[1]);

       if (roleName.equals(RoleType.USER.getName()))
           return userValidationService.findByUserId(id).getToken();
       return managerValidationService.findByManagerId(id).getToken();
    }
}
